package com.chukun.concurrency.singleton;

import com.chukun.concurrency.annotations.UnThreadSafe;

/**
 * 使用懒汉式创建单例对象,会有线程安全的问题
 * 如何解决线程安全的问题？？？？
 */
@UnThreadSafe
public class SingletonBuilder3 {

    private static SingletonBuilder3 instance;
    private SingletonBuilder3(){}

    /**
     * 双向检查机制，也会出现线程安全的问题
     * 创建一个对象分为三步,
     * 1.分配内存空间 allocate(1024)
     * 2.创建对象  new Object()
     * 3.创建的对象指向分配的内存空间
     *
     * jvm与cpu优化，会导致指令重排序
     *
     * 可能会导致如下的执行顺序
     * 1.分配内存空间 allocate(1024)
     * 3.创建的对象指向分配的内存空间
     * 2.创建对象  new Object()
     *
     * 这时，多线程调用此方法时，就会出现线程安全的问题
     *
     * 例如:
     *    A线程执行到  instance = new SingletonBuilder3(); 但是执行的是重排序的指向内存空间
     *    B 这时B线程进来，看到 instance不为空，直接return，但是这时对象还没创建
     *
     *    解决办法：使用volatile关键字，防止指定重排序
     *
     * @return
     */
    public static SingletonBuilder3 getInstance(){
        if(instance==null) {//双向检测
            synchronized (SingletonBuilder3.class) {//同步锁
                if(instance==null)
                    instance = new SingletonBuilder3();
            }
        }
        return instance;
    }


}
